package com.dhecp.core.genericDao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;

import com.dhecp.project.common.domain.ModuleNID;
import com.dhecp.project.common.domain.RecordCheck;

/**
 * GenericDao
 */
public interface GenericDao<T, PK extends Serializable> {
    /**
     * 插入一个实体（在数据库INSERT一条记录）
     *
     * @param entity 实体对象
     */
    int insert(T entity);

    /**
     * 修改一个实体对象（UPDATE一条记录）
     *
     * @param entity 实体对象
     * @return 修改的对象个数，正常情况=1
     */
    int update(T entity);

    /**
     * 修改删除标志
     * @param entity
     * @return
     * @author DH-Xxj
     */
    int updateDeleted(T entity);

    /**
     * 修改流程状态及生效标志
     * @param entity
     * @return
     * @author DH-Xxj
     */
    int updateFlow(T entity);

    /**
     * 修改符合条件的记录
     * <p>
     * 此方法特别适合于一次性把多条记录的某些字段值设置为新值（定值）的情况，比如修改符合条件的记录的状态字段
     * </p>
     * <p>
     * 此方法的另一个用途是把一条记录的个别字段的值修改为新值（定值），此时要把条件设置为该记录的主键
     * </p>
     *
     * @param param 用于产生SQL的参数值，包括WHERE条件、目标字段和新值等
     * @return 修改的记录个数，用于判断修改是否成功
     */
    int update(DynamicSqlParameter param);
    
    /**
    *@Description: 根据guid查询单条数据
    *@Param: [guid]
    *@return: int
    *@Author: hlf
    *@date: 2022-08-17 14:50
    */
    T findById(Map<String, Object> params);
    List<T> findByIdList (Map<String, Object> params);

    /**
     * 按主键删除记录
     *
     * @param primaryKey 主键对象
     * @return 删除的对象个数，正常情况=1
     */
    int delete(PK primaryKey);

    /**
     * 删除符合条件的记录
     * <p>
     * <strong>此方法一定要慎用，如果条件设置不当，可能会删除有用的记录！</strong>
     * </p>
     *
     * @param param 用于产生SQL的参数值，包括WHERE条件（其他参数内容不起作用）
     * @return
     */
    int delete(DynamicSqlParameter param);

    /**
     * 删除记录，传入要删除记录的实体
     * @param entity
     * @return
     * @author DH-Xxj
     */
    int delete(T entity);
    
    /**
     * 清空表，比delete具有更高的效率，而且是从数据库中物理删除（delete是逻辑删除，被删除的记录依然占有空间）
     * <p>
     * <strong>此方法一定要慎用！</strong>
     * </p>
     *
     * @return
     */
    int truncate();

    /**
     * 查询整表总记录数
     *
     * @return 整表总记录数
     */
    int count();

    /**
     * 查询符合条件的记录数
     *
     * @param param 查询条件参数，包括WHERE条件（其他参数内容不起作用）。此参数设置为null，则相当于count()
     * @return
     */
    int count(DynamicSqlParameter param);

    /**
     * 按主键取记录
     *
     * @param primaryKey 主键值
     * @return 记录实体对象，如果没有符合主键条件的记录，则返回null
     */
    T get(PK primaryKey);

    /**
     * 按主键取记录
     *
     * @param primaryKey 主键值
     * @return 记录实体对象，如果没有符合主键条件的记录，则 throw DataAccessException
     */
    T load(PK primaryKey) throws DataAccessException;

    /**
     * 取全部记录
     *
     * @return 全部记录实体对象的List
     */
    List<T> select();

    /**
     * 取整单记录
     *
     * @return 全部记录实体对象的List
     */
    List<T> selectGroup();

    /**
     * 取全部分组（整单）记录
     *
     * @return 全部记录实体对象的List
     */
    List<T> selectgroup();

    /**
     * 按条件查询记录
     * @param param 查询条件参数，包括WHERE条件、分页条件、排序条件
     * @return 符合条件记录的实体对象的List
     */
    List<T> select(DynamicSqlParameter param);

    /**
     * 按条件查询整单记录
     * @param param 查询条件参数，包括WHERE条件、分页条件、排序条件
     * @return 符合条件记录的实体对象的List
     */
    List<T> selectGroup(DynamicSqlParameter param);

    /**
     * 按条件查询记录
     * @param param 查询条件参数，包括WHERE条件、数据权限条件、分页条件、排序条件
     * @return
     * @author DH-Xxj
     */
    List<T> select(Map<String, Object> params);

    /**
     * 按条件查询整单记录
     * @param param 查询条件参数，包括WHERE条件、数据权限条件、分页条件、排序条件
     * @return
     * @author DH-Xxj
     */
    List<T> selectGroup(Map<String, Object> params);

    /**
     * 按条件查询分组（整单）记录
     * @param param 查询条件参数，包括WHERE条件、数据权限条件、分页条件、排序条件
     * @return
     * @author DH-Xxj
     */
    List<T> selectgroup(Map<String, Object> params);

    T selectOne(DynamicSqlParameter param);

    /**
     * 按条件查询记录，并处理成分页结果
     *
     * @param param 查询条件参数，包括WHERE条件、分页条件、排序条件
     * @return PaginationResult对象，包括（符合条件的）总记录数、页实体对象List等
     */
    PaginationResult<T> selectPagination(
            DynamicSqlParameter param);

    /**
     * 按条件查询记录，并把有外键关联的字段的关联对象也处理出来
     * <p>
     * 此方法是为了避免1+N而设置的
     * </p>
     *
     * @param param 查询条件参数，包括WHERE条件、分页条件、排序条件<strong>（不包括外键关联表条件）</strong>
     * @return 符合条件记录的实体对象的List
     */
    List<T> selectFk(DynamicSqlParameter param);

    /**
     * 按条件查询记录，并把有外键关联的字段的关联对象也处理出来，并处理成分页结果
     * <p>
     * 此方法是为了避免1+N而设置的
     * </p>
     *
     * @param param 查询条件参数，包括WHERE条件、分页条件、排序条件<strong>（不包括外键关联表条件）</strong>
     * @return PaginationResult对象，包括（符合条件的）总记录数、页实体对象List等
     */
    PaginationResult<T> selectFkPagination(
            DynamicSqlParameter param);

    /**
     * 批量插入
     *
     * @param list
     */
    int batchInsert(final List<T> list);

    /**
     * 批量修改
     *
     * @param list
     */
    int batchUpdate(final List<T> list);

    /**
     * 批量删除
     *
     * @param list
     */
    int batchDelete(final List<PK> list);
    

	/**
	 * 验证单据中相关记录是否存在，以判断（增、删、改）操作
	 * @param nid 必要参数： 单据编码
	 * @return List - RecordCheck
	 * @author DH-Xxj
	 */
	List<RecordCheck> findRecords(@Param("nid") String nid);
	
	/**
	 * 查询前一单NID
	 * @param nid 必要参数：当前 单据编码
	 * @return ModuleNID NID实体
	 * @author DH-Xxj
	 */
	ModuleNID selectLastNid(Map<String, Object> params);

	/**
	 * 查询后一单NID
	 * @param nid 必要参数：当前 单据编码
	 * @return ModuleNID NID实体
	 * @author DH-Xxj
	 */
	ModuleNID selectNextNid(Map<String, Object> params);
	
	/**
	 * 查询指定单nid的首记录
	 * @param nid 必要参数：当前 单据编码
	 * @return StockOfferPrice 实体
	 * @author DH-Xxj
	 */
	T selectFirstRecordByNid(Map<String, Object> params);
	
	/**
	 * 查询指定单nid的整单录
	 * @param nid 必要参数：当前 单据编码
	 * @return StockOfferPrice 实体
	 * @author DH-Xxj
	 */
	List<T> selectByNid(Map<String, Object> params);
}
